﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using WHC.Security.BLL;
using System.Collections;
using WHC.Security.Entity;

namespace WHC.Security.UI
{
    public partial class FrmEditTree : BaseForm
    {
        public enum DisplayTreeType  { OU, Role, User, Function }
        public DisplayTreeType DisplayType;
        public string RoleID = string.Empty;//在Role中查看其他相关信息的时候
        public string OUID = string.Empty;//在OU中查看用户列表的时候
        public string UserID = string.Empty;//在User的时候查看功能列表

        private List<int> removeList = new List<int>();
        private List<int> addList = new List<int>();
        private Role roleBll = new Role();
        private OU ouBLL = new OU();

        //CListItem Text=Name, Value = PID
        private Dictionary<int, CListItem> checkedDict = new Dictionary<int, CListItem>();//记录用户原来选择的内容
        private Dictionary<int, CListItem> treeDict = new Dictionary<int, CListItem>();//记录所有列表的内容

        public FrmEditTree()
        {
            InitializeComponent();
        }

        private void FrmEditTree_Load(object sender, EventArgs e)
        {
            RefreshTreeView();
        }

        private void RefreshTreeView()
        {
            ArrayList list = new ArrayList();
            ArrayList chechedList = new ArrayList();

            #region 根据不同条件获取不同的列表
            switch (DisplayType)
            {
                case DisplayTreeType.OU:
                    #region OU
                    OU ou = new OU();
                    list.AddRange(ou.GetAll());

                    if (!string.IsNullOrEmpty(RoleID))
                    {
                        chechedList.AddRange(ou.GetOUsByRole(Convert.ToInt32(RoleID)));
                    }

                    if (chechedList == null)
                    {
                        chechedList = new ArrayList();
                    }

                    foreach (OUInfo info in chechedList)
                    {
                        if (!checkedDict.ContainsKey(info.ID))
                        {
                            checkedDict.Add(info.ID, new CListItem(info.Name, info.PID.ToString()));
                        }
                    }
                    foreach (OUInfo info in list)
                    {
                        if (!treeDict.ContainsKey(info.ID))
                        {
                            treeDict.Add(info.ID, new CListItem(info.Name, info.PID.ToString()));
                        }
                    } 
                    #endregion
                    break;

                case DisplayTreeType.Role:
                    #region Role
                    Role role = new Role();
                    list.AddRange(role.GetAll());

                    if (!string.IsNullOrEmpty(OUID))
                    {
                        chechedList.AddRange(role.GetRolesByOU(Convert.ToInt32(OUID)));
                    }
                    if (chechedList == null)
                    {
                        chechedList = new ArrayList();
                    }

                    foreach (RoleInfo info in chechedList)
                    {
                        if (!checkedDict.ContainsKey(info.ID))
                        {
                            checkedDict.Add(info.ID, new CListItem(info.Name, "-1"));
                        }
                    }
                    foreach (RoleInfo info in list)
                    {
                        if (!treeDict.ContainsKey(info.ID))
                        {
                            treeDict.Add(info.ID, new CListItem(info.Name, "-1"));
                        }
                    } 
                    #endregion
                    break;

                case DisplayTreeType.User:
                    #region User
                    User user = new User();
                    list.AddRange(user.GetAll());

                    if (!string.IsNullOrEmpty(RoleID))
                    {
                        chechedList.AddRange(user.GetUsersByRole(Convert.ToInt32(RoleID)));
                    }
                    else if (!string.IsNullOrEmpty(OUID))
                    {
                        chechedList.AddRange(user.GetUsersByOU(Convert.ToInt32(OUID)));
                    }

                    if (chechedList == null)
                    {
                        chechedList = new ArrayList();
                    }

                    foreach (UserInfo info in chechedList)
                    {
                        if (!checkedDict.ContainsKey(info.ID))
                        {
                            string name = string.Format("{0}（{1}）", info.Name, info.FullName);
                            checkedDict.Add(info.ID, new CListItem(name, info.PID.ToString()));
                        }
                    }
                    foreach (UserInfo info in list)
                    {
                        if (!treeDict.ContainsKey(info.ID))
                        {
                            string name = string.Format("{0}（{1}）", info.Name, info.FullName);
                            treeDict.Add(info.ID, new CListItem(name, info.PID.ToString()));
                        }
                    } 
                    #endregion
                    break;

                case DisplayTreeType.Function:
                    #region Function
                    Function function = new Function();
                    list.AddRange(function.GetAll());

                    if (!string.IsNullOrEmpty(RoleID))
                    {
                        chechedList.AddRange(function.GetFunctionsByRole(Convert.ToInt32(RoleID)));
                    }
                    else if (!string.IsNullOrEmpty(UserID))
                    {
                        chechedList.AddRange(function.GetFunctionsByUser(Convert.ToInt32(UserID), ""));
                    }

                    if (chechedList == null)
                    {
                        chechedList = new ArrayList();
                    }

                    foreach (FunctionInfo info in chechedList)
                    {
                        if (!checkedDict.ContainsKey(info.ID))
                        {
                            checkedDict.Add(info.ID, new CListItem(info.Name, info.PID.ToString()));
                        }
                    }
                    foreach (FunctionInfo info in list)
                    {
                        if (!treeDict.ContainsKey(info.ID))
                        {
                            treeDict.Add(info.ID, new CListItem(info.Name, info.PID.ToString()));
                        }
                    } 
                    #endregion
                    break;
            } 
            #endregion

            treeView1.Nodes.Clear();
            treeView1.BeginUpdate();
            Cursor.Current = Cursors.WaitCursor;

            foreach(int key in treeDict.Keys)
            {
                if (treeDict[key].Value != "-1")
                {
                    continue;
                }

                TreeNode item = new TreeNode();
                item.Name = key.ToString();
                item.Text = treeDict[key].Text;
                item.Tag = treeDict[key].Text;
                item.Checked = checkedDict.ContainsKey(key);
                this.treeView1.Nodes.Add(item);

                AddChildNode(item);
            }

            Cursor.Current = Cursors.Default;
            treeView1.EndUpdate();
            this.treeView1.ExpandAll();
        }

        private void AddChildNode(TreeNode fnode)
        {
            foreach (int key in treeDict.Keys)
            {
                if (treeDict[key].Value != fnode.Name)
                {
                    continue;
                }
                TreeNode item = new TreeNode();
                item.Name = key.ToString();
                item.Text = treeDict[key].Text;
                item.Tag = treeDict[key].Text;
                item.Checked = checkedDict.ContainsKey(key);
                fnode.Nodes.Add(item);

                AddChildNode(item);
            }
        }

        private void GetChanges(TreeNode node)
        {
            int id = Convert.ToInt32(node.Name);
            if (!node.Checked && checkedDict.ContainsKey(id))
            {
                removeList.Add(id);
            }
            if (node.Checked && !checkedDict.ContainsKey(id))
            {
                addList.Add(id);
            }

            foreach (TreeNode subNode in node.Nodes)
            {
                GetChanges(subNode);
            }
        }

        private void btnOK_Click(object sender, EventArgs e)
        {
            foreach (TreeNode node in this.treeView1.Nodes)
            {
                GetChanges(node);
            }

            #region 根据不同条件获取不同的列表
            switch (DisplayType)
            {
                case DisplayTreeType.OU:
                    foreach (int id in removeList)
                    {
                        if (!string.IsNullOrEmpty(RoleID))
                        {
                            roleBll.RemoveOU(id, Convert.ToInt32(RoleID));
                        }
                    }
                    foreach (int id in addList)
                    {
                        if (!string.IsNullOrEmpty(RoleID))
                        {
                            roleBll.AddOU(id, Convert.ToInt32(RoleID));
                        }
                    }
                    break;

                case DisplayTreeType.Role:
                    break;

                case DisplayTreeType.User:
                    foreach (int id in removeList)
                    {
                        if (!string.IsNullOrEmpty(RoleID))
                        {
                            roleBll.RemoveUser(id, Convert.ToInt32(RoleID));
                        }
                        else if (!string.IsNullOrEmpty(OUID))
                        {
                            ouBLL.RemoveUser(id, Convert.ToInt32(OUID));
                        }
                    }         
                    foreach (int id in addList)
                    {
                        if (!string.IsNullOrEmpty(RoleID))
                        {
                            roleBll.AddUser(id, Convert.ToInt32(RoleID));
                        }
                        else if (!string.IsNullOrEmpty(OUID))
                        {
                            ouBLL.AddUser(id, Convert.ToInt32(OUID));
                        }
                    }
                    break;

                case DisplayTreeType.Function:
                    foreach (int id in removeList)
                    {
                        if (!string.IsNullOrEmpty(RoleID))
                        {
                            roleBll.RemoveFunction(id, Convert.ToInt32(RoleID));
                        }
                    }
                    foreach (int id in addList)
                    {
                        if (!string.IsNullOrEmpty(RoleID))
                        {
                            roleBll.AddFunction(id, Convert.ToInt32(RoleID));
                        }
                    }
                    break;
            }
            #endregion
        }

        private void chkAll_CheckedChanged(object sender, EventArgs e)
        {
            foreach (TreeNode node in this.treeView1.Nodes)
            {
                CheckSelect(node, this.chkAll.Checked);
            }
        }

        private void CheckSelect(TreeNode node, bool selectAll)
        {
            node.Checked = selectAll;
            foreach (TreeNode subNode in node.Nodes)
            {
                CheckSelect(subNode, selectAll);
            }
        }
    }
}
